<?php
namespace app\common\process;

use think\Log;

class Pay extends Base {
    protected $request = null;

    //获取request
    public function getRequest() {
        if($this->request == null) {
            $this->request = loader()->loadAny('request', 'jy\\Pay');
        }
        return $this->request;
    }

	//订单
	public function order($user) {
    	$post = $this->getRequest()->get_private_id();
        $route = $this->getRequest()->get_route();

    	$validate = loadValidate('jy\\Pay');
    	if(!$validate->scene('order')->check($post)) {
    		$this->error($validate->getError());
    	}

        if($route == 'miniprogram2') {
            return $this->pay_single($post);
            //return $this->pay_service($post);
        } else if($route == 'miniprogram_oxy') {
            return $this->pay_service($post);
        } else {
            return $this->pay_single($post);
        }
	}

    //微信小店创建订单
    public function createorder($post) {
        $options = loadStorage('Login')->token2options();
        $redis = loader()->loadAny('redis', 'redis');
        $cache = $redis->getArray('pay_order_' . $post['id']);
        if($cache) {
            //return $cache;
        }
        $app = loadTool('Wechat');
        $order = loadOnly('Model')->find('jy\\Order', $post['id']);
        $data = [
            "openid" => $options['openid'],
            "combine_trade_no" => 'P' . $order['out_trade_no'],
            "expire_time" => time(),
            "sub_orders" =>[
                [
                    "mchid" => $order['sub_mch_id'],
                    "amount" => $order['total_fee'],
                    "trade_no" => $order['out_trade_no'],
                    "description" => $order['sname'] . '订单'
                ]
            ]
        ];
        $parameters = $app->createorder($data);
        $redis->setArray('pay_order_' . $post['id'], $parameters, 7200);
        return $parameters;
    }

    //服务商订单
    public function pay_service($post) {
        $app = loadTool('Wechat')->payment();
        $options = loadStorage('Login')->token2options();
        $redis = loader()->loadAny('redis', 'redis');
        $cache = $redis->getArray('pay_order_' . $post['id']);
        $route = $this->getRequest()->get_route();
        if($cache) {
            return $cache;
        }

        $order = loadOnly('Model')->find('jy\\Order', $post['id']);
  
        $profitSharing = loadEnum('ProfitSharing');
        $profit_sharing = $order->getData('profit_sharing');
        if($profit_sharing == $profitSharing->code2key('bufenzhang')) {
            $profit_sharing = '';
        }

        $attach = [
            'route' => $route
        ];

        $result = $app->order->unify([
            'body' => '商品描述',
            'out_trade_no' => $order['out_trade_no'],
            'total_fee' => $order['total_fee'] * 100,
            'notify_url' => 'https://' . $_SERVER['HTTP_HOST'] . '/miniprogram/pay/pay_service_notify',
            'spbill_create_ip' => $order['spbill_create_ip'],
            'trade_type' => 'JSAPI',
            'openid' => $options['openid'],
            'profit_sharing' => $profit_sharing, // 表明该笔订单需要分账
            'sub_mch_id' => $order['sub_mch_id'],
            'attach' => json_encode($attach)
        ]);
         Log::Info('pay_service----' . 'https://' . $_SERVER['HTTP_HOST'] . '/miniprogram/pay/pay_service_notify');

        $statusEnum = loadEnum('OrderStatus');
        //$order->save(['status' => $statusEnum->code2key('guanbidingdan')]);

        if ($result['return_code'] === 'SUCCESS' && $result['result_code'] === 'SUCCESS') {
            $prepayId = $result['prepay_id'];
            // 生成 JSAPI 支付参数
            $jssdk = $app->jssdk;
            $parameters = $jssdk->bridgeConfig($prepayId, false);
            $redis->setArray('pay_order_' . $post['id'], $parameters, 7200);
            return $parameters;
        } else {
            $msg = $result['return_msg'] == 'OK' ? $result['err_code_des'] : $result['return_msg'];
            
            $errorMessage = "支付失败，订单号：{$order['out_trade_no']}，错误信息：{$msg}";
            Log::error($errorMessage);
            $this->error($msg);
        }
    }

    //非服务商创建订单
    public function pay_single($post) {
        $app = loadTool('Wechat')->payment();
        $options = loadStorage('Login')->token2options();
        $redis = loader()->loadAny('redis', 'redis');
        $route = $this->getRequest()->get_route();
        $cache = $redis->getArray($route . '_pay_order_' . $post['id']);
        
        if($cache) {
            //return $cache;
        }

        $order = loadOnly('Model')->find('jy\\Order', $post['id']);
        $statusEnum = loadEnum('OrderStatus');

        if($order['balance'] == $order['total_fee']) {
            $order->save(['status' => $statusEnum->code2key('daifahuo'), 'transaction_id' => 'balance', 'pay_type' => loadEnum('PayType')->code2key('balance'), 'paytime' => time(), 'route' => $route]);
            return $this->success('支付成功');
        }
  
        $profitSharing = loadEnum('ProfitSharing');
        $profit_sharing = $order->getData('profit_sharing');
        if($profit_sharing == $profitSharing->code2key('bufenzhang')) {
            $profit_sharing = '';
        }

        $attach = [
            'route' => $route
        ];

        $result = $app->order->unify([
            'body' => '商品描述',
            'out_trade_no' => $order['out_trade_no'],
            'total_fee' => ($order['total_fee'] - $order['balance']) * 100,
            'notify_url' => 'https://' . $_SERVER['HTTP_HOST'] . '/miniprogram/pay/notify',
            'spbill_create_ip' => $order['spbill_create_ip'],
            'trade_type' => 'JSAPI',
            'openid' => $options['openid'],
            'profit_sharing' => $profit_sharing, // 表明该笔订单需要分账
            //'sub_mch_id' => $order['sub_mch_id']
            'attach' => json_encode($attach)
        ]);

        //$statusEnum = loadEnum('OrderStatus');
        //$order->save(['status' => $statusEnum->code2key('guanbidingdan')]);

        if ($result['return_code'] === 'SUCCESS' && $result['result_code'] === 'SUCCESS') {
            $prepayId = $result['prepay_id'];
            // 生成 JSAPI 支付参数
            $jssdk = $app->jssdk;
            $parameters = $jssdk->bridgeConfig($prepayId, false);
            $redis->setArray($route . '_pay_order_' . $post['id'], $parameters, 7200);
            return $parameters;
        } else {
            $msg = $result['return_msg'] == 'OK' ? $result['err_code_des'] : $result['return_msg'];
            
            $errorMessage = "支付失败，订单号：{$order['out_trade_no']}，错误信息：{$msg}";
            Log::error($errorMessage);
            $this->error($msg);
        }
    }

    //非服务商创建订单强制不分账
    public function pay_single_n($post) {
        $app = loadTool('Wechat')->payment();
        $options = loadStorage('Login')->token2options();
        $redis = loader()->loadAny('redis', 'redis');
        $cache = $redis->getArray($route . '_pay_order_' . $post['id']);
        $route = $this->getRequest()->get_route();
        if($cache) {
            //return $cache;
        }

        $order = loadOnly('Model')->find('jy\\Order', $post['id']);

        $attach = [
            'route' => $route
        ];

        $result = $app->order->unify([
            'body' => '商品描述',
            'out_trade_no' => $order['out_trade_no'],
            'total_fee' => ($order['total_fee'] - $order['balance']) * 100,
            'notify_url' => 'https://' . $_SERVER['HTTP_HOST'] . '/miniprogram/pay/notify',
            'spbill_create_ip' => $order['spbill_create_ip'],
            'trade_type' => 'JSAPI',
            'openid' => $options['openid'],
            'profit_sharing' => '', // 表明该笔订单需要分账
            //'sub_mch_id' => $order['sub_mch_id']
            'attach' => json_encode($attach)
        ]);

        $statusEnum = loadEnum('OrderStatus');
        //$order->save(['status' => $statusEnum->code2key('guanbidingdan')]);

        if ($result['return_code'] === 'SUCCESS' && $result['result_code'] === 'SUCCESS') {
            $prepayId = $result['prepay_id'];
            // 生成 JSAPI 支付参数
            $jssdk = $app->jssdk;
            $parameters = $jssdk->bridgeConfig($prepayId, false);
            $redis->setArray($route . '_pay_order_' . $post['id'], $parameters, 7200);
            return $parameters;
        } else {
            $msg = $result['return_msg'] == 'OK' ? $result['err_code_des'] : $result['return_msg'];
            
            $errorMessage = "支付失败，订单号：{$order['out_trade_no']}，错误信息：{$msg}";
            Log::error($errorMessage);
            $this->error($msg);
        }
    }

    public function notify($app, $pay_type) {
        Log::info('notify--1');
        $response = $app->handlePaidNotify(function ($message, $fail) use ($pay_type) {
            Log::info('notify--message');
            Log::info('notify--json_encode($message)');
            if ($message['return_code'] === 'SUCCESS') {
                Log::info('notify--2');
                if ($message['result_code'] === 'SUCCESS') {
                    $orderModel = loadOnly('Model')->getModel('jy\\Order');
                    $userModel = loadOnly('Model')->getModel('tyyh\\User');
                    Log::info('notify--3');
                    $row = $orderModel->where(['out_trade_no' => $message['out_trade_no']])->find();
                    if($row['paytime'] > 0) {
                        return '';
                    }
                    try {
                        $orderModel->startTrans();
                        $userModel->startTrans();
                        Log::info('notify--4');
                        if(empty($row)) {
                            Log::error($message['out_trade_no'] . '订单不存在');
                            throw new \Exception($message['out_trade_no'] . '订单不存在');
                        }
                        Log::info('notify--5');
                        $statusEnum = loadEnum('OrderStatus');

                        $attach = $message['attach'];
                        $attach = json_decode($attach, true);
                        if($row->take_type == 0) {
                            $row->save(['status' => $statusEnum->code2key('daifahuo'), 'transaction_id' => $message['transaction_id'], 'pay_type' => $pay_type, 'paytime' => time(), 'route' => $attach['route']]);
                        } else {
                            $row->save(['status' => $statusEnum->code2key('daiziti'), 'transaction_id' => $message['transaction_id'], 'pay_type' => $pay_type, 'paytime' => time(), 'route' => $attach['route']]);
                        }
                        Log::info('notify--6');
                        $user = $userModel->find($row['uid']);
                        $user->order_num = $user->order_num + 1;
                        $user->save();
                        Log::info('notify--7');
                        $groupBuyingPromotionStatus = loadEnum('GroupBuyingPromotionStatus');
                        $groupBuyingModel = loadModel('tyyh\\GroupBuying');
                        Log::info('notify--8');
                        $groupBuyingLvEnum = loadEnum('GroupBuyingLv');
                        $spreadid = $row['spreadid'];
                        $status = $groupBuyingPromotionStatus->code2key('yizhifu');
                        Log::info('notify--9');
                        if($spreadid) {
                            $datas = [];
                            $rate = $groupBuyingLvEnum->code2rate('tuanzhang');
                            $datas[] = [
                                'uid'             => $row['spreadid'],
                                'oid'             => $row['id'],
                                'commission'      => $row['commission'] * $rate / 100,
                                'commission_rate' => $rate,
                                'status'          => $status
                            ];
                            Log::info('notify--10');
                            $prow = $groupBuyingModel->where(['uid' => $spreadid])->find();
                            Log::info('notify--11');
                            if($prow['puid'] > 0) {
                                $grow = $groupBuyingModel->where(['uid' => $prow['puid']])->find();
                                Log::info('notify--12');
                                if($grow['lv'] >= 1) {
                                    $rate = $groupBuyingLvEnum->code2rate('jingli');
                                    $datas[] = [
                                        'uid'             => $grow['uid'],
                                        'oid'             => $row['id'],
                                        'commission'      => $row['commission'] * $rate / 100,
                                        'commission_rate' => $rate,
                                        'status'          => $status
                                    ];
                                    Log::info('notify--13');
                                    if($grow['puid'] > 0 ) {
                                        Log::info('notify--14');
                                        $ggrow = $groupBuyingModel->where(['uid' => $grow['puid']])->find();
                                        Log::info('notify--15');
                                        if($ggrow['lv'] >= 2) {
                                            Log::info('notify--16');
                                            $rate = $groupBuyingLvEnum->code2rate('zongjian');
                                            Log::info('notify--17');
                                            $datas[] = [
                                                'uid'             => $ggrow['uid'],
                                                'oid'             => $row['id'],
                                                'commission'      => $row['commission'] * $rate / 100,
                                                'commission_rate' => $rate,
                                                'status'          => $status
                                            ];
                                            Log::info('notify--18');
                                        }
                                    }
                                }
                            }
                            Log::info('notify--18');
                            loadModel('tyyh\\GroupBuyingPromotion')->isUpdate(false)->saveAll($datas);
                            Log::info('notify--19');
                        }
                        Log::info('支付成功，订单号：' . $message['out_trade_no'] . ',支付前状态为' . $row['status']);
                        Log::info('notify--20');
                        $orderModel->commit();
                        $userModel->commit();
                        trigger('after_pay', [$row], 'miniprogram');
                        Log::info('notify--after_pay');
                        Log::info('notify--21');
                    } catch(\Exception $e) {
                        $orderModel->rollback();
                        $userModel->rollback();
                        Log::error($e->getMessage());
                    }
                    Log::info('notify--22');
                    return true;
                } else {
                    $errorMessage = "支付失败，订单号：{$message['out_trade_no']}，错误信息：{$message['err_code_des']}";
                    Log::error($errorMessage);
                    return $fail('支付失败');
                }
            } else {
                $errorMessage = "支付通知通信失败，订单号：{$message['out_trade_no']}，错误信息：{$message['return_msg']}";
                Log::error($errorMessage);
                return $fail('通信失败');
            }
        });
        return $response;
    }
}
